package cs3343.project.family.UI;

import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextPane;
import javax.swing.border.EmptyBorder;

import cs3343.project.family.Card;
import cs3343.project.family.CardController;
import cs3343.project.family.Character;
import cs3343.project.family.CharacterController;
import cs3343.project.family.ConfigManager;
import cs3343.project.family.GameController;
import cs3343.project.family.UIController;

/**
 * The Class EventCardFrame.
 */
public class EventCardFrame extends JDialog implements ActionListener {

	/** The content pane. */
	private JPanel contentPane;
	
	/** The gc. */
	private GameController gc;
	
	/** The character controller. */
	private CharacterController characterController;
	
	/** The ui controller. */
	private UIController uiController;
	
	/** The card controller. */
	private CardController cardController;
	
	/** The description panel. */
	private JPanel descriptionPanel;
	
	/** The tool card panel. */
	private JPanel toolCardPanel;
	
	/** The option panel. */
	private JPanel optionPanel;
	
	/** The okay. */
	private JButton okay;
	
	/** The description. */
	private JTextPane description;
	
	/** The btn_ a. */
	private JButton btn_A;
	
	/** The btn_ b. */
	private JButton btn_B;
	
	/** The btn_ c. */
	private JButton btn_C;
	
	/** The btn_ d. */
	private JButton btn_D;
	
	/** The msg. */
	private JLabel msg;
	
	/** The option. */
	private String[] option;
	
	/** The available card. */
	private JComboBox<String> availableCard;
	
	/** The btn_confirm. */
	private JButton btn_confirm;
	
	/** The current player. */
	private Character currentPlayer;
	
	/** The current card. */
	private Card currentCard;
	
	/** The card picked. */
	private boolean cardPicked;

	/**
	 * Create the frame.
	 *
	 * @param player the player
	 * @param card the card
	 * @param gc the gc
	 */
	public EventCardFrame(Character player, Card card, GameController gc) {
		setModal(true);
		setResizable(false);
		setTitle(ConfigManager.getLangString("eventCardFrameTitle"));
		
		this.gc = gc;
		
		characterController = this.gc.getCharacterController();
		uiController = this.gc.getUiController();
		cardController = this.gc.getCardController();
		initUI();
		
		cardPicked = false;
		
		currentPlayer = player;
		currentCard = card;
		
		descriptionPanel = new JPanel();
		toolCardPanel = new JPanel();
		optionPanel = new JPanel();
		
		okay = new JButton(ConfigManager.getLangString("btnOkay"));		
		btn_confirm = new JButton(ConfigManager.getLangString("btnConfirmUseCard"));
		btn_A = new JButton(currentCard.getOption(0));
		btn_B = new JButton(currentCard.getOption(1));
		btn_C = new JButton(currentCard.getOption(2));
		btn_D = new JButton(currentCard.getOption(3));
		
		description = new JTextPane();
		description.setText(card.getDescription());
		description.setEditable(false);
		msg = new JLabel(" ", JLabel.CENTER);
		Font f = new Font("Dialog", Font.PLAIN, 20);
	    msg.setFont(f);
		
		option = currentPlayer.getAvailableCards("EventCard", cardController);
		availableCard = new JComboBox(option);
	    
	    descriptionPanel.setLayout(new BorderLayout());
	    toolCardPanel.setLayout(new BorderLayout());
	    optionPanel.setLayout(new GridLayout(3, 2));
		
		getContentPane().add(descriptionPanel, BorderLayout.NORTH);
		getContentPane().add(msg, BorderLayout.CENTER);
		getContentPane().add(optionPanel, BorderLayout.SOUTH);

		descriptionPanel.add(description, BorderLayout.NORTH);
		descriptionPanel.add(toolCardPanel, BorderLayout.CENTER);
		
		toolCardPanel.add(new JLabel(" "), BorderLayout.NORTH);
		toolCardPanel.add(availableCard, BorderLayout.CENTER);
		toolCardPanel.add(btn_confirm, BorderLayout.SOUTH);
		
		
		optionPanel.add(btn_A);
		optionPanel.add(btn_B);
		optionPanel.add(btn_C);
		optionPanel.add(btn_D);
		optionPanel.add(new JLabel(""));
		
		optionPanel.add(okay);
		okay.setEnabled(false);
		activateToolCardButton();
		
		btn_confirm.addActionListener(this);
		btn_A.addActionListener(this);
		btn_B.addActionListener(this);
		btn_C.addActionListener(this);
		btn_D.addActionListener(this);
		okay.addActionListener(this);
	}
	
	/**
	 * Inits the ui.
	 */
	private void initUI() {
		setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
		setBounds(500, 350, 450, 250);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		contentPane.setLayout(new BorderLayout(0, 0));
		setContentPane(contentPane);
	}
	
	/**
	 * Activate tool card button.
	 */
	private void activateToolCardButton() {
		if (option[0].equalsIgnoreCase(ConfigManager.getLangString("msgNoCardOption")))
			btn_confirm.setEnabled(false);
	}
	
	/* (non-Javadoc)
	 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
	 */
	@Override
	public void actionPerformed(ActionEvent e) {	
		if (e.getSource() == btn_confirm) {
			if (!option[0].equalsIgnoreCase(ConfigManager.getLangString("msgNoCardOption")))
				if ((String) availableCard.getSelectedItem() != ConfigManager.getLangString("msgCardOption")) {	
					availableCard.setEnabled(false);
					btn_confirm.setEnabled(false);
					cardPicked = true;
					cardApplication();
				}
    	}
		
		if (e.getSource() == btn_A) {
			buttonEffect(btn_A, cardPicked, 0);
		}
		else if (e.getSource() == btn_B) {
			buttonEffect(btn_B, cardPicked, 1);
		}
		else if (e.getSource() == btn_C) {
			buttonEffect(btn_C, cardPicked, 2);
		}
		else if (e.getSource() == btn_D) {
			buttonEffect(btn_D, cardPicked, 3);
		}		
		else if (e.getSource() == okay) {
			gc.afterPressed();
			this.dispose();
		}
    }
	
	/**
	 * Button effect.
	 *
	 * @param btn the btn
	 * @param cardPicked the card picked
	 * @param option the option
	 */
	public void buttonEffect(JButton btn, boolean cardPicked, int option) {
		availableCard.setEnabled(false);
		btn_confirm.setEnabled(false);

		btn_A.setEnabled(true);
		btn_B.setEnabled(true);
		btn_C.setEnabled(true);
		btn_D.setEnabled(true);
		
		btn_A.setVisible(false);
		btn_B.setVisible(false);
		btn_C.setVisible(false);
		btn_D.setVisible(false);
		
		btn.setEnabled(false);
		btn.setVisible(true);
    	okay.setEnabled(true);
    	
    	if (cardPicked) {
			for (int i = 1; i <= cardController.getNumOfMagicToolCard(); i++) {
				if ((String) availableCard.getSelectedItem() == cardController.getMagicToolCard(String.valueOf(i)).getDescription()) {
					switch (i) {
						case 5: currentPlayer.removeCard(cardController.getMagicToolCard(String.valueOf(i))); toolCard5(option); break;
						case 6: currentPlayer.removeCard(cardController.getMagicToolCard(String.valueOf(i))); toolCard6(option); break;
					}
				}
			}
    	}
		else {
			
			for (int i = 0; i < characterController.getNumOfPlayer(); i++) {
				int oriEsteem = characterController.getPlayer(i).getEsteem();
				gc.updateEsteem(characterController.getPlayer(i), oriEsteem += Integer.parseInt(currentCard.getResult(option)), "回答事件卡");
			}
			msg.setText(ConfigManager.getLangString("msgUpdateAllEsteem") + currentCard.getResult(option));
		}

    	for (int i = 0; i < characterController.getNumOfPlayer(); i++) {
    		uiController.getGameFrame().setPlayerEsteemLabel(i);
    	}
	}
	
	
	/**
	 * Card application.
	 */
	public void cardApplication() {
		for (int i = 1; i <= cardController.getNumOfMagicToolCard(); i++) {
			if ((String) availableCard.getSelectedItem() == cardController.getMagicToolCard(String.valueOf(i)).getDescription()) {
				switch (i) {
					case 2: currentPlayer.removeCard(cardController.getMagicToolCard(String.valueOf(i))); toolCard2_4(); break;
					case 4: currentPlayer.removeCard(cardController.getMagicToolCard(String.valueOf(i))); toolCard2_4(); break;
					case 7: currentPlayer.removeCard(cardController.getMagicToolCard(String.valueOf(i))); toolCard7(); break;
					case 8: currentPlayer.removeCard(cardController.getMagicToolCard(String.valueOf(i))); toolCard8(); break;
					case 9: currentPlayer.removeCard(cardController.getMagicToolCard(String.valueOf(i))); toolCard9(); break;
					case 10: currentPlayer.removeCard(cardController.getMagicToolCard(String.valueOf(i))); toolCard10(); break;
				}
			}
		}
	}
	
	//tool card function
	
	//2	[事件]	工具卡	免一次事件。
	//4	[說話/事件/動作]	工具卡	免一次說話/事件/動作。
	/**
	 * Tool card2_4.
	 */
	public void toolCard2_4() {
		btn_A.setEnabled(false);
		btn_B.setEnabled(false);
		btn_C.setEnabled(false);
		btn_D.setEnabled(false);
		okay.setEnabled(true);
		msg.setText(ConfigManager.getLangString("msgSkipCard"));
	}
	
	//5	[說話/事件/動作]	保護罩	可保護使用者即使無法完成任務也不用扣自尊值。
	/**
	 * Tool card5.
	 *
	 * @param option the option
	 */
	public void toolCard5(int option) {

		if (Integer.parseInt(currentCard.getResult(option)) < 0)
	    	msg.setText(ConfigManager.getLangString("msgNoPenalty"));
		else {
	    	msg.setText(ConfigManager.getLangString("msgUpdateEsteem") + currentCard.getResult(option));
	    	int oriEsteem = currentPlayer.getEsteem();
	    	gc.updateEsteem(currentPlayer, oriEsteem += Integer.parseInt(currentCard.getResult(option)), "使用工具卡: 保護罩");
		}
			
	}
	
	//6	[說話/事件/動作]	工具卡	當遇到事件卡，如完成任務可獲得雙倍自尊值，無法完成任務不扣自尊值。
	/**
	 * Tool card6.
	 *
	 * @param option the option
	 */
	public void toolCard6(int option) {
		if (Integer.parseInt(currentCard.getResult(option)) < 0)
	    	msg.setText(ConfigManager.getLangString("msgNoPenalty"));
		else {
			int addEsteem = Integer.parseInt(currentCard.getResult(option));
	    	msg.setText(ConfigManager.getLangString("msgUpdateEsteem") + addEsteem * 2);
	    	int oriEsteem = currentPlayer.getEsteem();
	    	gc.updateEsteem(currentPlayer, oriEsteem += addEsteem * 2, "使用工具卡: 工作卡6");
		}
	}
	
	//7	[說話/事件/動作]	工具卡	當遇到說話/事件/動作卡，可放棄該卡，再抽一次同類型的卡。
	/**
	 * Tool card7.
	 */
	public void toolCard7() {
		int ranCard = (int)(cardController.getNumOfEventCard() * Math.random() + 1);
		Card card = cardController.getEventCard(String.valueOf(ranCard));
		
		uiController.showEventCardFrame(card, currentPlayer);
		this.setVisible(false);
	}
	
	/**
	 * Tool card8.
	 */
	public void toolCard8() {
	    Character selectedPlayer = gc.selectCharacter(ConfigManager.getLangString("msgChoosePlayerTitle"), ConfigManager.getLangString("msgChoosePlayer"));
	    		currentPlayer = selectedPlayer;
	    
	    System.out.println(currentPlayer);
	    cardPicked = false;
	}
	
	//9	[事件]	工具卡	當遇到事件卡，直接加自尊值100，無需答題。
	/**
	 * Tool card9.
	 */
	public void toolCard9() {
		btn_A.setEnabled(false);
		btn_B.setEnabled(false);
		btn_C.setEnabled(false);
		btn_D.setEnabled(false);
		msg.setText(ConfigManager.getLangString("msgUpdateEsteem") + "+100");
    	int oriEsteem = currentPlayer.getEsteem();
    	gc.updateEsteem(currentPlayer, oriEsteem += 100, "使用工具卡: 工作卡9");
		okay.setEnabled(true);
	}	
	
	//10[事件]	工具卡	當遇到事件卡，直接加自尊值50，無需答題。
	/**
	 * Tool card10.
	 */
	public void toolCard10() {
		btn_A.setEnabled(false);
		btn_B.setEnabled(false);
		btn_C.setEnabled(false);
		btn_D.setEnabled(false);
		msg.setText(ConfigManager.getLangString("msgUpdateEsteem") + "+50");
    	int oriEsteem = currentPlayer.getEsteem();
    	gc.updateEsteem(currentPlayer, oriEsteem += 50, "使用工具卡: 工作卡10");
		okay.setEnabled(true);
	}
	
	/**
	 * Gets the available card.
	 *
	 * @return the available card
	 */
	public JComboBox<String> getAvailableCard() {
		return this.availableCard;
	}
}